﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets._2D;

public class MovingPlatform : MonoBehaviour
{

    public LayerMask collisionLayers;
    public List<Rigidbody2D> connectedBodies;
    private Rigidbody2D _rigidbody2D;

    public bool isHeal = false;
    public float DamageInterval = 0.25f;
    public float DamagePerSecond = 4f;
    private float _accumulatedTime;

    //private Vector2 lastPos;
    // Start is called before the first frame update
    void Awake()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
        if (!_rigidbody2D) _rigidbody2D = GetComponentInParent<Rigidbody2D>();
        connectedBodies = new List<Rigidbody2D>();
        //_joint = GetComponent<Joint2D>();
        //if (!_joint) _joint = GetComponentInParent<Joint2D>();
        //SliderJoint2D sliderJoint = (SliderJoint2D) _joint;
        //if (sliderJoint) sliderJoint.angle = 90f;
        //lastPos = Vector2.zero;
    }

    private void Start()
    {
        _accumulatedTime = 0f;
    }

    private void FixedUpdate()
    {
        _accumulatedTime += Time.fixedDeltaTime;
        bool shouldDamage = false;
        if (_accumulatedTime >= DamageInterval)
        {
            _accumulatedTime -= DamageInterval;
            shouldDamage = true;
        }
        foreach (Rigidbody2D connectedBody in connectedBodies)
        {
            if (connectedBody && connectedBody.position.y > _rigidbody2D.position.y)
            {
                Vector2 desiredMovement = _rigidbody2D.GetPointVelocity(connectedBody.position) * Time.fixedDeltaTime;
                connectedBody.position = connectedBody.position + desiredMovement;

            }
        }

        if (shouldDamage) ApplyDamageToBodies();

        //Vector2 deltaPos =  _rigidbody2D.position - lastPos;
        //Debug.Log(deltaPos.x + " vs " + _rigidbody2D.velocity.x * Time.fixedDeltaTime);
        //lastPos = _rigidbody2D.position;
    }

    // Update is called once per frame
    private void OnCollisionEnter2D(Collision2D otherCollision2D)
    {
        
        if (((1 << otherCollision2D.collider.gameObject.layer) & collisionLayers) > 0)
        {
            Rigidbody2D otherBody = otherCollision2D.collider.attachedRigidbody;
            if (otherBody)
            {
                Connect(otherBody);
                PlatformerCharacter2D character = otherBody.GetComponent<PlatformerCharacter2D>();
                if (character)
                {
                    character.touchingPlatform = this;
                    ApplyDamageTo(character);
                }
            }
            
            
            //connectedBody.velocity += _rigidbody2D.velocity;
            //_joint.connectedBody = otherCollision2D.collider.attachedRigidbody;
        }

        //otherCollision2D.transform.parent = transform;
    }

    private void OnCollisionExit2D(Collision2D otherCollision2D)
    {
        Rigidbody2D otherBody = otherCollision2D.collider.attachedRigidbody;
        if (connectedBodies.Contains(otherBody))
        {
            PlatformerCharacter2D character = otherBody.GetComponent<PlatformerCharacter2D>();
            if (character) character.touchingPlatform = null;
            Disconnect(otherBody);
            //_joint.connectedBody = null;
        }

        //otherCollision2D.transform.parent = null;
    }

    public void Connect(Rigidbody2D rigidbody2D)
    {
        if (!connectedBodies.Contains(rigidbody2D))
        {
            connectedBodies.Add(rigidbody2D);
        }
        
    }

    public void Disconnect(Rigidbody2D rigidbody2D)
    {
        connectedBodies.Remove(rigidbody2D);
    }

    private void ApplyDamageToBodies()
    {
        List<Rigidbody2D> bodies = new List<Rigidbody2D>();
        foreach (Rigidbody2D connectedBody in connectedBodies)
        {
            if (connectedBody && connectedBody.position.y > _rigidbody2D.position.y)
            {
                bodies.Add(connectedBody);
                

            }
        }

        foreach (Rigidbody2D body in bodies)
        {
            ApplyDamageTo(body.GetComponent<PlatformerCharacter2D>());
        }
        
    }

    public void ApplyDamageTo(PlatformerCharacter2D character2D)
    {
        if (!Mathf.Approximately(DamagePerSecond, 0f))
        {
            float dmg = DamagePerSecond * DamageInterval;
            if (isHeal)
            {
                character2D.RecoverHealth(dmg);
            }
            else
            {
                character2D.TakeDamage(dmg);
            }
        }
        
    }
}